import React, { ReactNode, useRef, useState } from 'react'
import { Upload, Button, message, Progress } from 'antd'
import { UploadOutlined } from '@ant-design/icons'
import type { RcFile } from 'antd/es/upload/interface'
import { checkChunks, mergeChunks, uploadsFile } from '~/api/file'
import { FileUpload, UserFile } from '~/types'
import SparkMD5 from 'spark-md5'
import Modal, { CustomModalHandles } from '../Modal'
interface FileUploadProps extends UserFile {
  children?: ReactNode // 可选的 children 属性
  changeFile: () => void // 可选的 changeFile 属性
}
const FileUpload: React.FC<FileUploadProps> = ({
  userId,
  folderId,
  children,
  changeFile
}) => {
  const [progress, setProgress] = useState(0)
  const [uploading, setUploading] = useState(false)
  const modalRef = useRef<CustomModalHandles>(null)
  //获取文件MD5，注意这里谷歌浏览器有最大文件限制当文件大于2G时浏览器无法读取文件
  const getFileMD5 = (file: RcFile): Promise<any> => {
    return new Promise((resolve, reject) => {
      const fileReader = new FileReader()
      fileReader.onload = (e) => {
        if (e.target?.result instanceof ArrayBuffer) {
          const fileMd5 = SparkMD5.ArrayBuffer.hash(e.target.result)
          resolve(fileMd5)
        }
      }
      fileReader.onerror = (e) => {
        reject(e)
      }
      fileReader.readAsArrayBuffer(file)
    })
  }

  const handleUpload = async (file: RcFile) => {
    const chunkSize = 5 * 1024 * 1024 // 5MB chunk size
    const fileSize = file.size
    const fileId = await getFileMD5(file)
    setProgress(0) // Reset progress
    setUploading(true) // Start uploading

    // 如果是空数组或者数组中有未上传的分片就要上传分片
    const totalChunks = Math.ceil(fileSize / chunkSize)
    console.log('🚀 ~ handleUpload ~ totalChunks:', totalChunks)
    if (totalChunks > 1) {
      // 请求接口查询是不是上传过分片
      const { data } = await checkChunks({ fileId, userId, folderId })
      for (let i = 0; i < totalChunks; i++) {
        // 如果data中没有当前分片的索引，说明该分片未上传
        if (data!.length === 0 || data![i] === 0) {
          const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize)
          const chunkInfo: FileUpload = {
            userId,
            folderId,
            file,
            chunk,
            index: i,
            totalChunks,
            fileId
          }
          await uploadsFile(chunkInfo)
        }
        // 更新进度条，无论分片是否上传
        await setProgress((prevProgress) => prevProgress + 100 / totalChunks)
      }
    } else {
      const chunkInfo: FileUpload = {
        userId,
        folderId,
        file,
        totalChunks,
        fileId
      }
      await uploadsFile(chunkInfo)
      await setProgress((prevProgress) => prevProgress + 100 / totalChunks)
    }

    // All chunks uploaded, now notify the server to merge them
    try {
      totalChunks > 1 &&
        (await mergeChunks({
          fileId,
          totalChunks,
          userId,
          folderId,
          originalName: file.name
        }))
    } catch (error) {
      console.error('Error merging file chunks:', error)
    }

    await setUploading(false) // Finish uploading
    changeFile()
  }

  const beforeUpload = (file: RcFile) => {
    handleUpload(file)
    showModal()
    // Prevent the default behavior of the Upload component
    return false
  }
  const showModal = () => {
    modalRef.current?.openModal()
  }
  const handleFileNew = async () => {
    modalRef.current?.closeModal()
  }
  return (
    <>
      <Upload beforeUpload={beforeUpload} showUploadList={false}>
        {children}
      </Upload>
      <Modal ref={modalRef} title='上传文件中...' onConfirm={handleFileNew}>
        <Progress percent={progress} status='active' />
      </Modal>
    </>
  )
}

export default FileUpload
